#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import sys

from dws.commons.common import is_main_job, log
from common.util.check_utils import is_valid_id
from dws.commons.parse_param import parse_param_with_jsonschema
from common.common import exter_attack
from dws.backup.cluster_backup import ClusterBackup
from dws.commons.const import RestoreSubtaskName, TaskType
from dws.commons.dws_param_parse import DwsParamParse
from dws.commons.job_info import JobInfo
from dws.restore.parse_restore_job import ParseRestoreJobParam
from dws.restore.roach_restore_job import RoachRestoreJob


def get_backup_job_info(pid):
    """
    获取备份参数
    """
    param = parse_param_with_jsonschema(pid)
    is_main_task = is_main_job(param)
    job_info = JobInfo(
        pid=pid,
        type=TaskType.BACKUP.value,
        job_id=DwsParamParse.get_job_id(param),
        copy_id=DwsParamParse.get_copy_id(param),
        backup_tool_type=DwsParamParse.get_backup_tool_type(param),
        usr=DwsParamParse.get_user_name(param),
        env_path=DwsParamParse.get_env_path(param),
        sub_job_type=DwsParamParse.get_sub_job_name(param),
        nodes=DwsParamParse.get_nodes(param),
        backup_type=DwsParamParse.get_type(param),
        agents=DwsParamParse.get_agents(param),
        failed_agents=DwsParamParse.get_failed_agents(param),
        pro_obj=DwsParamParse.get_protect_obj(param),
        cluster_agents=DwsParamParse.get_cluster_agents(param),
        host_agents=DwsParamParse.get_host_agents(param))

    return is_main_task, job_info


def get_restore_job_info(pid, main_task_id):
    """
    获取恢复的参数
    """
    is_main_task = True
    job_info = None
    restore_job_param = ParseRestoreJobParam(pid)
    user_name, env_path = restore_job_param.get_target_cluster_auth_info()
    subtask_name = restore_job_param.get_subtask_name()
    if subtask_name:
        is_main_task = False
    if subtask_name == RestoreSubtaskName.WHILE_LIST_SUBTASK:
        subtask_name = "prepare"
    if subtask_name == RestoreSubtaskName.CLEAN_SUBTASK:
        subtask_name = "clean"
    if subtask_name == RestoreSubtaskName.RESTORE_SUBTASK:
        # 原集群的恢复，只能在备份的节点做恢复
        restore_obj = RoachRestoreJob(restore_job_param)
        if not restore_obj.restore_can_run_in_local_node():
            return is_main_task, job_info

    job_info = JobInfo(
        pid=pid,
        job_id=main_task_id,
        type=TaskType.RESTORE.value,
        copy_id=restore_job_param.get_copy_id(),
        backup_tool_type=restore_job_param.get_copy_generate_type(),
        usr=user_name,
        env_path=env_path,
        sub_job_type=subtask_name,
        nodes=restore_job_param.get_restore_param().get("job", {}).get("targetEnv", {}).get("nodes", []))
    return is_main_task, job_info


@exter_attack
def do_exec(task_type, pid, main_task_id):
    log.info(f"Enter, pid: {pid}.")
    job_info = None
    is_main_task = True
    if task_type == "backup":
        is_main_task, job_info = get_backup_job_info(pid)
    elif task_type == "restore":
        is_main_task, job_info = get_restore_job_info(pid, main_task_id)

    if not job_info:
        log.error(f"Get job info failed, pid: {pid}.")
        return False
    log.info(f'Allow_running: {job_info}')

    try:
        if not ClusterBackup(pid).allow_running_in_local_node(job_info, is_main_task):
            raise Exception('Allow_running exec failed')
    except Exception as err_str:
        log.error(f"End with {err_str}, {job_info.log_format()}.")
        return False

    log.info(f'Allow_running suc, {job_info.log_format()}.')
    return True


if __name__ == '__main__':
    if len(sys.argv) < 4:
        log.error("Param is wrong.")
        sys.exit(1)

    if not is_valid_id(sys.argv[2]):
        log.warn(f"pid is invalid")
        sys.exit(1)

    if not is_valid_id(sys.argv[3]):
        log.warn(f"main_task_id is invalid")
        sys.exit(1)

    try:
        do_exec(sys.argv[1], sys.argv[2], sys.argv[3])
    except Exception as err:
        log.error(err)
        sys.exit(1)

    sys.exit(0)
